<script lang="ts" setup name="FsSelect">
import { Option, OptionValue, SelectModelValue } from '../FsSearchSelect/type.ts';
import { ref, watch } from 'vue';

type Props = {
  modelValue?: SelectModelValue;
  // 初始化选项函数，返回promise
  requestMethod?: () => Promise<Option[]>;
  // 初始选项列表，用于回显时初始化
  options?: Option[];
  // 是否显示值在右边
  showValue?: boolean;
  multiple?: boolean;
  // 是否使用虚拟化选择器，数据量大时开启
  virtualized?: boolean;
};

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  options: () => [],
  multiple: false
});

const emits = defineEmits(['update:modelValue', 'change']);

const innerOptions = ref<Option[]>(props.options || []);

const inValue = ref<SelectModelValue>(props.modelValue);

const modelValueHandle = (value: SelectModelValue) => {
  inValue.value = value;
  emits('update:modelValue', value);
};

const changeHandle = (value: SelectModelValue) => {
  let selected;
  if (props.multiple) {
    selected = innerOptions.value.filter(item => (value as OptionValue[]).indexOf(item.value) > -1);
  } else {
    selected = innerOptions.value.find(item => {
      return item.value == value;
    });
  }
  emits('change', { value, selected });
};

let allData: any = innerOptions.value
if(props.requestMethod) {
  props.requestMethod().then(data => {
    allData = data
    innerOptions.value = data
  })
}

const filterMethod = (keyword: string) => {
  innerOptions.value = allData.filter((item: any) => item.value.indexOf(keyword) > -1 || item.label.indexOf(keyword) > -1)
}

watch(
  () => props.modelValue,
  val => {
    inValue.value = val;
  },
);

watch(() => props.options, (val) => {
  innerOptions.value = val
})

</script>
<template>
  <el-select
    v-if="!virtualized"
    class="w-full"
    :model-value="inValue"
    :multiple="multiple"
    :filter-method="filterMethod"
    v-bind="$attrs"
    @update:modelValue="modelValueHandle"
    @change="changeHandle">
    <el-option
      v-for="item in innerOptions"
      :key="item.value"
      :value="item.value"
      :label="item.label">
      <slot name="option" :item="item">
        <span style="float: left;">{{ item.label }}</span>
        <span v-if="showValue" style="float: right; color: #8492a6;">[{{ item.value }}]</span>
      </slot>
    </el-option>
  </el-select>
  <el-select-v2
    v-else
    class="w-full"
    :model-value="inValue"
    :multiple="multiple"
    :options="innerOptions"
    v-bind="$attrs"
    @update:modelValue="modelValueHandle"
    @change="changeHandle">
    <template #default="{ item }">
      <span style="float: left;">{{ item.label }}</span>
      <span v-if="showValue" style="float: right; color: #8492a6;">[{{ item.value }}]</span>
    </template>
  </el-select-v2>
</template>
